home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / rw / writePS.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  6KB  |  253 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1993, David Koblas (koblas@netcom.com)                  | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <stdio.h>
  16. #include "image.h"
  17. #ifdef sco
  18. #include <time.h>
  19. #else
  20. #include <sys/time.h>
  21. #endif
  22. #include <string.h>
  23.  
  24. #ifndef TRUE
  25. #define TRUE    1
  26. #define FALSE    0
  27. #endif
  28.  
  29. static void writePreview(FILE *fd, Image *image)
  30. {
  31. }
  32.  
  33. static void writeCmap(FILE *fd, Image *image)
  34. {
  35.     int        runlen, maxCount;
  36.     int        col, used;
  37.     int        i, x, y;
  38.     unsigned char    *ucp;
  39.     char        buf[280];
  40.     short        map[256];
  41.     int        isRLE;
  42.  
  43.     /*
  44.     **  Remap the colors to the number used
  45.     */
  46.     for (i = 0; i < 256; i++)
  47.         map[i] = -1;
  48.     for (ucp = image->data, y = 0; y < image->width * image->height; y++, ucp++)
  49.         map[*ucp] = 1;
  50.     for (used = i = 0; i < 256; i++) {
  51.         if (map[i] != -1)
  52.             map[i] = used++;
  53.     }
  54.  
  55.     /*
  56.     **  If compression will help
  57.     */
  58.     fprintf(fd, "/rgbmap %d string def\n", used * 3);
  59.     fputs("% RLE drawing routine                    \n\
  60. /buffer 2 string def                            \n\
  61. /rgb (000) def                                \n\
  62. /drawcolormappedimage {                            \n\
  63.   /buffer  1   string def                        \n\
  64.   /rgbval  3   string def                        \n\
  65.   /npixels 384 string def    % 128 * 3                \n\
  66.   { currentfile buffer readhexstring pop  % read run information    \n\
  67.     /len exch 0 get store                        \n\
  68.     len 128 ge                                \n\
  69.     { 0 1 len 128 sub    % this is a run of raw data            \n\
  70.       { currentfile buffer readhexstring pop pop            \n\
  71.         /rgbval rgbmap buffer 0 get 3 mul 3 getinterval store        \n\
  72.         npixels exch 3 mul rgbval putinterval                \n\
  73.       } for                                \n\
  74.       npixels 0 len 127 sub 3 mul getinterval                \n\
  75.     }                                    \n\
  76.     { % else it's run data                        \n\
  77.       currentfile buffer readhexstring pop pop                \n\
  78.       /rgbval rgbmap buffer 0 get 3 mul 3 getinterval store        \n\
  79.       0 1 len { npixels exch 3 mul rgval putinterval } for        \n\
  80.       npixels 0 len 1 add 3 mul getinterval                \n\
  81.     } ifelse                                \n\
  82.   }                                    \n\
  83.   false 3 colorimage                            \n\
  84. } bind def\n", fd);
  85.  
  86.     fprintf(fd, "%%%% get the rgb map\n");
  87.     fprintf(fd, "currentfile rgbmap readhexstring\n");
  88.  
  89.     ucp = image->cmapData;
  90.     for (col = i = 0; i < image->cmapSize; i++, ucp += 3) {
  91.         if (map[i] == -1)
  92.             continue;
  93.         
  94.         fprintf(fd, "%02.2x%02.2x%02.2x ", ucp[0], ucp[1], ucp[2]);
  95.         if (++col == 10) {
  96.             putc('\n', fd);
  97.             col = 0;
  98.         }
  99.     }
  100.     if (col != 0)
  101.         putc('\n', fd);
  102.     fprintf(fd, "pop pop\n\n");
  103.  
  104.     fprintf(fd, "%d %d 8\n", image->width, image->height);
  105.     fprintf(fd, "[ %d 0 0 -%d 0 %d ]\n", 
  106.             image->width, image->height, image->height);
  107.     fprintf(fd, "drawcolormappedimage\n");
  108.  
  109.     ucp      = image->data;
  110.     maxCount = 0x7f;
  111.  
  112. #define PUT(fd, val) do {            \
  113.     fprintf(fd, "%02.2x", val);        \
  114.     if (++col == 35)            \
  115.         { col = 0; putc('\n', fd); }    \
  116.     } while (0)
  117.     
  118. #define    WRITE(fd, flg, buf, len) do { int _i;            \
  119.     PUT(fd, (len) + (flg ? 0 : 128));            \
  120.     if (flg)                         \
  121.         PUT(fd, map[buf[0]]);                \
  122.     else                            \
  123.         for (_i = 0; _i < (len); _i++)            \
  124.             PUT(fd, map[buf[_i]]);            \
  125.     putc(' ', fd);                        \
  126.     } while (0)
  127.  
  128.     col = 0;
  129.     for (y = 0; y < image->height; y++) {
  130.         int    prev;
  131.  
  132.         runlen = 0;
  133.         for (x = 0; x < image->width; x++, ucp++) {
  134.             int    v = *ucp;
  135.  
  136.             if (runlen == 0) {
  137.                 isRLE = TRUE;
  138.             } else if (runlen == maxCount) {
  139.                 WRITE(fd, isRLE, buf, runlen);
  140.                 runlen  = 0;
  141.                 isRLE     = TRUE;
  142.             } else if (isRLE  && v != prev) {
  143.                 if (runlen == 1) {
  144.                     isRLE = FALSE;
  145.                 } else {
  146.                     WRITE(fd, isRLE, buf, runlen);
  147.                     runlen = 0;
  148.                 }
  149.             } else if (!isRLE && v == prev) {
  150.                 WRITE(fd, isRLE, buf, runlen);
  151.                 buf[0]   = prev;
  152.                 runlen   = 1;
  153.                 isRLE    = TRUE;
  154.             }
  155.             buf[runlen++] = v;
  156.             prev          = v;
  157.         }
  158.  
  159.         if (runlen != 0)
  160.             WRITE(fd, isRLE, buf, runlen);
  161.         col = 0;
  162.         putc('\n', fd);
  163.     }
  164.     putc('\n', fd);
  165. #undef WRITE
  166. #undef PUT
  167. }
  168.  
  169. static void writeRGB(FILE *fd, Image *image)
  170. {
  171.     unsigned char    *ucp;
  172.     int        x, y;
  173.     int        col;
  174.  
  175.     fprintf(fd, "/line %d string def\n", image->width * 3);
  176.     fprintf(fd, "%d %d 8\n", image->width, image->height);
  177.     fprintf(fd, "[ %d 0 0 -%d 0 %d ]\n", 
  178.             image->width, image->height, image->height);
  179.     fprintf(fd, "{currentfile line readhexstring pop}\n");
  180.     fprintf(fd, "false 3 colorimage\n");
  181.  
  182.     for (y = 0; y < image->height; y++) {
  183.         for (x = 0; x < image->width; x++) {
  184.             ucp = ImagePixel(image, x, y);
  185.             fprintf(fd, "%02.2x%02.2x%02.2x", ucp[0], ucp[1], ucp[2]);
  186.             if (++col == 12) {
  187.                 putc('\n', fd);
  188.                 col = 0;
  189.             }
  190.         }
  191.     }
  192.     if (col != 0)
  193.         putc('\n', fd);
  194. }
  195.  
  196. int WritePS(char *file, Image *image)
  197. {
  198.     FILE        *fd;
  199.     char        *cp, buf[256];
  200.     unsigned char    *ucp;
  201.     unsigned short    *usp;
  202.     time_t        t;
  203.  
  204.     if ((fd = fopen(file, "w")) == NULL)
  205.         return 1;
  206.  
  207.     if ((cp = strrchr(file, '/')) == NULL)
  208.         cp = file;
  209.     else
  210.         cp++;
  211.     strcpy(buf, cp);
  212.     if ((cp = strrchr(buf, '.')) != NULL)
  213.         *cp = '\0';
  214.  
  215.     time(&t);
  216.     fprintf(fd, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  217.     fprintf(fd, "%%%%Creator: XPaint\n%%%%Title: %s\n%%%%Pages: 1\n", buf);
  218.     fprintf(fd, "%%%%BoundingBox: %d %d %d %d\n", 0, 0, image->width, image->height);
  219.     fprintf(fd, "%%%%CreationDate: %s", ctime(&t));
  220.     fprintf(fd, "%%%%EndComments\n");
  221.  
  222.     /*
  223.     **  Write a preview image
  224.     */
  225.  
  226.     writePreview(fd, image);
  227.  
  228.     fprintf(fd, "%%%%EndProlog\n%%%%Page: 1 1\n");
  229.     fprintf(fd, "\n\ngsave\n\n");
  230.  
  231.     /*
  232.     **  Write the actual image
  233.     */
  234.  
  235.     fprintf(fd, "/inch {72 mul} def\n");
  236.     fprintf(fd, "%d %d scale\n", image->width, image->height);
  237.  
  238. #if 0
  239.     if (image->cmapSize == 0 || image->cmapSize > 256)
  240.         writeRGB(fd, image);
  241.     else
  242.         writeCmap(fd, image);
  243. #else
  244.         writeRGB(fd, image);
  245. #endif
  246.  
  247.     fprintf(fd, "%%\n\ngrestore\nshowpage\n%%%%Trailer\n");
  248.  
  249.     fclose(fd);
  250.  
  251.     return 0;
  252. }
  253.